import socket

# step , generate socket object
from threading import Thread

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# bind to address info
server.bind(("10.2.0.243", 7777))
clients = []
# listen
server.listen(10)
print("The server is running ......")

users = {}


def do_chat(client):
    client_socket, (address, port) = client
    login_info = client_socket.recv(65535).decode("utf-8")
    cmd, username = login_info.split(":")
    if cmd == "login":
        for user, sock in users.items():
            sock.send("notify:system:{} is online".format(username).encode("utf-8"))
        users[username] = client_socket
    else:
        client_socket.send("Unknown command")

    while True:
        try:
            data = client_socket.recv(65535).decode("utf-8")
            if not data:
                raise ConnectionError
        except ConnectionError:
            del users[username]
            for user, sock in users.items():
                sock.send("notify:system:{} is offline".format(username).encode("utf-8"))
            client_socket.close()
            break

        cmd, recver, message = data.split(":")
        if recver not in users:
            client_socket.send("message:system:对方不在线!!!!稍后在发".encode("utf-8"))
            continue
        print("{} said to {}: {}".format(username, recver, message))
        recv_so = users[recver]
        recv_so.send("message:{}:{}".format(username, message).encode("utf-8"))


while True:
    client_info = server.accept()
    Thread(target=do_chat, args=(client_info,), daemon=True).start()

    # client_socket, (address, port) = client_info
    # for c in clients:
    #     c.send("{} is online".format((address, port)).encode("utf-8"))
    # clients.append(client_socket)
    # print("The client {} is connected.".format(address, port))
    # client_socket.send(data.encode("utf-8"))
# TODO: add code to recv/send
server.close()
